﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using FinanSoft.Entities;
using FinanSoft.BusinessLayer;
using FinanSoft.Utilities;
using FinanSoft.PresentacionContabilidad;

namespace FinanSoft
{
    public partial class frmAsientos : Form
    {
        List<AccountingEntryDetail> currentEntryDetails;
        int[] _typesIds;
        private int[] _periodIds;
        private int[] _seasonIds;

        public frmAsientos()
        {
            InitializeComponent();
            currentEntryDetails = new List<AccountingEntryDetail>();
            
            fillFields();
        }

        private void fillFields()
        {
            fillCodes();
            fillPeriods();
        }

        private void fillPeriods()
        {
            cmbPeriod.Items.Clear();
            cmbPeriod.Text = "";
            AccountingPeriod[] periods = PeriodManager.GetInstance().GetAccountingPeriod();
            _periodIds = new int[periods.Length];
            for (int periodIndex = 0; periodIndex < periods.Length; periodIndex++)
            {
                cmbPeriod.Items.Add(periods[periodIndex].Name);
                _periodIds[periodIndex] = periods[periodIndex].Id;
            }
            cmbPeriod.SelectedIndex = cmbPeriod.Items.Count - 1;
        }

        private void fillSeasons()
        {
            cmbSeason.Items.Clear();
            cmbSeason.Text = "";

            if (cmbPeriod.SelectedIndex != Constants.INVALID_ID)
            {
                AccountingPeriod selectedPeriod = PeriodManager.GetInstance().GetPeriod(_periodIds[cmbPeriod.SelectedIndex]);
                _seasonIds = new int[selectedPeriod.Seasons.Length];
                for (int seasonIndex = 0; seasonIndex < selectedPeriod.Seasons.Length; seasonIndex++)
                {
                    cmbSeason.Items.Add(selectedPeriod.Seasons[seasonIndex].Name);
                    _seasonIds[seasonIndex] = selectedPeriod.Seasons[seasonIndex].Id;
                }
                cmbSeason.SelectedIndex = cmbSeason.Items.Count - 1;
            }
        }

        private void fillCodes()
        {
            List<DocType> docTypes = DocumentTypeManager.GetInstance().Types;
            _typesIds = new int[docTypes.Count];
            for (int currencyIndex = 0; currencyIndex < docTypes.Count; currencyIndex++)
            {
                _typesIds[currencyIndex] = docTypes[currencyIndex].Id;
                cbDocType.Items.Add(docTypes[currencyIndex].Name);
            }

            if (cbDocType.Items.Count > 0)
            {
                cbDocType.SelectedIndex = 0;
                cbDocType.Enabled = false;
            }
        }

        private void btnNuevaLinea_Click(object sender, EventArgs e)
        {
            // Cargamos y mostramos el formulario AgregarLinea
            frmAgregarLinea frmAgregarLineaV = new frmAgregarLinea(this);
            frmAgregarLineaV.ShowDialog(this);     // Mostramos el formulario de forma modal.
        }

        public void AgregarLinea(int idCuenta, string cuenta, double monto, int idMoneda, string nombreMoneda, bool credito, int idCuentaAuxiliar)
        {
            Constants.AccountingEntryType type;
            DataGridViewRow newRow = new DataGridViewRow();
            double montoLocal;
            double montoSistema;
            Currency monedaAsiento;

            //TODO Validar que haya tipo de cambio para la moneda ingresada, sino, desplegar error
            monedaAsiento = MoneyManager.GetInstance().GetCurrency(idMoneda);
            montoLocal = Math.Round(monedaAsiento.ToLocalCurrency * monto, 2);
            montoSistema = Math.Round(montoLocal / MoneyManager.GetInstance().SystemCurrency.ToLocalCurrency, 2);

            string localSymbol = MoneyManager.GetInstance().LocalCurrency.Symbol;
            string systemSymbol = MoneyManager.GetInstance().SystemCurrency.Symbol;
            string entrySymbol = MoneyManager.GetInstance().GetCurrency(idMoneda).Symbol;

            newRow.CreateCells(gridAsientos);
            object[] parameters = credito ? new object[] { cuenta, 0, localSymbol + montoLocal.ToString("0.00"), 0, systemSymbol + montoSistema.ToString("0.00"), entrySymbol + monto.ToString("0.00"), nombreMoneda } : new object[] { cuenta, localSymbol + montoLocal.ToString("0.00"), 0, systemSymbol + montoSistema.ToString("0.00"), 0, entrySymbol + monto.ToString("0.00"), nombreMoneda };
            newRow.SetValues(parameters);            
            
            gridAsientos.Rows.Add(newRow);

            type = credito? Constants.AccountingEntryType.credit : Constants.AccountingEntryType.debit;

            currentEntryDetails.Add(AccountingEntryManager.GetInstance().BuildAccountingEntryDetail(idCuenta, montoSistema, montoLocal, type, idCuentaAuxiliar));
        }

        private void btnSalir_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void btnBorrarLinea_Click(object sender, EventArgs e)
        {
            int lineaActual; 
            
            if (!verifyTransactions())
            {
                MessageBox.Show(MessageConstants.NO_ROWS, MessageConstants.TITLE, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            if (gridAsientos.CurrentCell == null)
            {
                MessageBox.Show(MessageConstants.NO_CELL_SELECTED, MessageConstants.TITLE, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            lineaActual = gridAsientos.CurrentCell.RowIndex;

            if (gridAsientos.RowCount == 1)
            {
                gridAsientos.Rows.Clear();
                currentEntryDetails.RemoveAt(lineaActual);
                return;
            }

            if (lineaActual == gridAsientos.RowCount - 1)
            {
                return;
            }

            gridAsientos.Rows.RemoveAt(lineaActual);
            currentEntryDetails.RemoveAt(lineaActual);
            gridAsientos.Update();

        }

        private void btnGuardar_Click(object sender, EventArgs e)
        {
            if (validateFields())
            {
                int seasonId;

                seasonId = _seasonIds[cmbSeason.SelectedIndex];
                AccountingEntryManager.GetInstance().CreateAndRecordAccountingEntry(cbDocType.Text, dtpFechaIni.Value, dtpFechaFin.Value, seasonId, txtRef1.Text, txtRef2.Text, txtRef3.Text, currentEntryDetails);
                if (AccountingEntryManager.GetInstance().IsError)
                    MessageBox.Show(AccountingEntryManager.GetInstance().ErrorMessage, MessageConstants.TITLE, MessageBoxButtons.OK, MessageBoxIcon.Error);
                else
                {
                    MessageBox.Show(MessageConstants.ACCOUNTING_ENTRY_INSERTED, MessageConstants.TITLE, MessageBoxButtons.OK, MessageBoxIcon.Asterisk);                    
                    ClearFields();
                }
            }
        }

        private void ClearFields()
        {
            while (gridAsientos.Rows.Count > 1)
            {
                gridAsientos.Rows.RemoveAt(0); 
            }

            gridAsientos.Rows.Clear();

            currentEntryDetails = new List<AccountingEntryDetail>();
            cbDocType.SelectedIndex = - 1;
            cmbPeriod.SelectedIndex = Constants.INVALID_ID;
            cmbSeason.SelectedIndex = Constants.INVALID_ID;
            txtRef1.Text = "";
            txtRef2.Text = "";
            txtRef3.Text = "";

            gridAsientos.Update();
            
        }

        private bool validateFields()
        {

            if (!verifyTransactions())
            {
                MessageBox.Show(MessageConstants.MISSING_TRANSACTIONS, MessageConstants.TITLE, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return false;
            }


            if (cbDocType.SelectedIndex == Constants.INVALID_ID || cmbPeriod.SelectedIndex == Constants.INVALID_ID || cmbSeason.SelectedIndex == Constants.INVALID_ID)
            {
                MessageBox.Show(MessageConstants.MISSING_FIELDS, MessageConstants.TITLE, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return false;
            }

            return true;
        }

        private bool verifyTransactions()
        {
            if (currentEntryDetails.Count == 0)
                return false;
            return true;
        }

        private void cmbPeriod_SelectedIndexChanged(object sender, EventArgs e)
        {
            fillSeasons();
        }

        private void btnConsulta_Click(object sender, EventArgs e)
        {
            // Cargamos y mostramos el formulario de Consulta de Asientos
            frmConsultaAsientos frmConsultaAsientoV = new FinanSoft.PresentacionContabilidad.frmConsultaAsientos(this);
            frmConsultaAsientoV.ShowDialog(this);     // Mostramos el formulario de forma modal.
        }
    }
}
